﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using Microsoft.Phone.Info;
using DailyBread.DataServiceReference;
using System.Data.Services.Client;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.Net.Http;
using Newtonsoft.Json;
using DailyBread.Helpers;


namespace DailyBread
{
    public class Util
    {
        private const string baseAddress = "http://breadwebapi.azurewebsites.net/api/";
        // private const string baseAddress = "http://localhost:50243/api/";
        private const string httpPrefix = "http://odb.org/";

        private static string LikeAPIUri = baseAddress + "likes";
        private static string UnLikeAPIUri = baseAddress + "unlikes";
        private static string CommentAPIUri = baseAddress + "comments";
        private static string ContentAPIUri = baseAddress + "content";
        private static string LogAPIUri = baseAddress + "log";

        public static string GetPhoneOSAppInfo()
        {
            System.OperatingSystem osInfo = System.Environment.OSVersion;

            string modelname = null;
            object modelobject = null;
            if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue("DeviceName", out modelobject))
                modelname = modelobject as string;
            string ManufacturerName = "";
            object manufacturerobject;
            if (DeviceExtendedProperties.TryGetValue("DeviceManufacturer", out manufacturerobject))
                ManufacturerName = manufacturerobject.ToString();

            var versionAttrib = new AssemblyName(Assembly.GetExecutingAssembly().FullName);

            string version = versionAttrib.Version.ToString();

            return ManufacturerName + ' ' + modelname + ", " + osInfo.Version.ToString() + ", app:" + version;
        }

        public static Uri GetNavUrl(DateTime date)
        {
            StringBuilder urlToNavigate = new StringBuilder(date.Year.ToString(), 20);
            urlToNavigate.Append('/');
            if (date.Month < 10)
                urlToNavigate.Append('0');
            urlToNavigate.Append(date.Month);
            urlToNavigate.Append('/');
            if (date.Day < 10)
                urlToNavigate.Append('0');
            urlToNavigate.Append(date.Day);
            urlToNavigate.Insert(0, httpPrefix);
            urlToNavigate.Append("/");
            Uri uri = new Uri(urlToNavigate.ToString(), UriKind.Absolute);
            return uri;
        }

        public static string GetShortNavUrl(DateTime date)
        {
            StringBuilder urlToNavigate = new StringBuilder(date.Year.ToString(), 20);
            urlToNavigate.Append('-');
            if (date.Month < 10)
                urlToNavigate.Append('0');
            urlToNavigate.Append(date.Month);
            urlToNavigate.Append('-');
            if (date.Day < 10)
                urlToNavigate.Append('0');
            urlToNavigate.Append(date.Day);
            return urlToNavigate.ToString();
        }

        public static Uri GetImageUrl(DateTime date)
        {
            string imagUrlFormat = "http://d626yq9e83zk1.cloudfront.net/files/{0}/";
            string imageUrl = string.Format(imagUrlFormat, date.Year);

            if (date.Month < 10)
            {
                imageUrl += '0';
            }
            imageUrl += date.Month + "/";

            string imageUrlFormatTail = "{0}-770x425.jpg";
            string imageUrlTail = string.Format(imageUrlFormatTail, date.Day);

            if (date.Day < 10)
                imageUrl +='0';
            imageUrl += imageUrlTail;
     
            Uri uri = new Uri(imageUrl, UriKind.Absolute);
            return uri;
        }

        public static string GetUserId()
        {
            string userId;

            // get userid
            string anid = UserExtendedProperties.GetValue("ANID2") as string;
            if (anid == null)
            {
                string deviceId = DeviceExtendedProperties.GetValue("DeviceUniqueId") as string;
                if (deviceId == null)
                    userId = "public";
                else
                    userId = deviceId;
            }
            else
            {
                userId = anid.Substring(2, 32);
            }

            return userId;
        }

        #region Logs operation
        // store log entry into cache
        public static void AddToLog(string action)
        {
            LogCollection storedLog = IsolatedStorageHelper.GetObject<LogCollection>("Log");
            if (storedLog == null)
            {
                storedLog = new LogCollection();
                storedLog.LogList = new Collection<LogData>();
            }

            LogData newLog = new LogData();
            DateTime actionTime = System.DateTime.UtcNow;
            newLog.ActionTime = actionTime.ToString("yyyy/MM/dd HH:mm:ss.ffff");
            newLog.PartitionKey = actionTime.ToString("yyyyMMdd"); // use day of the year as partition key so that we can query per day data
            newLog.RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - actionTime.Ticks, Guid.NewGuid());
            newLog.UserId = GetUserId();
            newLog.UserAction = action;
            storedLog.LogList.Add(newLog);
            IsolatedStorageHelper.SaveObject("Log", storedLog);
        }

        // retrieve log from cache and send to server
        public static async void UploadLogToAzure()
        {
            LogCollection storedLog = IsolatedStorageHelper.GetObject<LogCollection>("Log");
            if (storedLog == null || storedLog.LogList == null)
                return;

            try
            {
                using (var client = new HttpClient())
                {
                    foreach (LogData log in storedLog.LogList)
                    {
                        string jsonLog = JsonConvert.SerializeObject(log);
                        StringContent msg = new StringContent(jsonLog, Encoding.UTF8, "application/json");
                        HttpResponseMessage ret = await client.PostAsync(new Uri(LogAPIUri), msg).ConfigureAwait(false);
                    }
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsolatedStorageHelper.DeleteObject("Log");
            }
        }
        #endregion

        #region Content operation
        public static void GetContentFromAzure(DateTime currentDate, 
                                                Action<BreadData> GetContentCallback,
                                                Action<Exception> OnError)
        {
            try
            {
                string BreadDate = Util.GetShortNavUrl(currentDate);
                string url = ContentAPIUri + "?BreadDate=" + BreadDate;
                Uri uri = new Uri(url);
                HttpService.Get(uri,
                    delegate(string result)
                    {
                        try
                        {
                            IEnumerable<BreadData> content = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<BreadData>>(result);
                            BreadData data = new BreadData();
                            data = content.First();
                            Deployment.Current.Dispatcher.BeginInvoke(() => { GetContentCallback(data); });
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                            Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
                        }
                    },
                    delegate(string uriString, Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
                    });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
            }
        }
        #endregion

        #region Comments operation
        public static void GetCommentsFromAzure(DateTime currentDisplayDate, 
                                                Action<IEnumerable<CommentData>> GetCommentsCallback,
                                                Action<Exception> OnError)
        {
            try
            {
                string BreadDate = Util.GetShortNavUrl(currentDisplayDate);
                string url = CommentAPIUri + "?BreadDate=" + BreadDate;
                Uri uri = new Uri(url);
                HttpService.Get(uri,
                    delegate(string result)
                    {
                        try
                        {
                            IEnumerable<CommentData> content = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<CommentData>>(result);
                            Deployment.Current.Dispatcher.BeginInvoke(() => { GetCommentsCallback(content); });
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());
                            Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
                        }
                    },
                    delegate(string uriString, Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
                    });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                Deployment.Current.Dispatcher.BeginInvoke(() => { OnError(ex); });
            }
        }

        public static async void SaveCommentToAzure(DateTime currentDisplayDate, 
                                              string commentText, 
                                              Action<string> SaveCommentCallback = null,
                                              Action<string> onError = null)
        {
            try
            {
                HttpResponseMessage msg;

                CommentData comment = new CommentData();
                comment.PartitionKey = currentDisplayDate.ToString("yyyyMMdd");
                comment.RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks, Guid.NewGuid());
                comment.BreadUrl = Util.GetShortNavUrl(currentDisplayDate);
                comment.Comment = commentText;

                string jsonComment = JsonConvert.SerializeObject(comment);
                StringContent content = new StringContent(jsonComment, Encoding.UTF8, "application/json");

                using (var client = new HttpClient())
                {
                    msg = await client.PostAsync(new Uri(CommentAPIUri), content).ConfigureAwait(false);
                    if (msg.IsSuccessStatusCode)
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() => { SaveCommentCallback(null); });
                    }
                    else
                    {
                        Debug.WriteLine(msg);
                        Deployment.Current.Dispatcher.BeginInvoke(() => { onError(msg.ToString()); });
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                Deployment.Current.Dispatcher.BeginInvoke(() => { onError(ex.ToString()); });
            }
        }

        public static void RemoveComment(DailyBreadComments comment,
                                         Action<DailyBreadComments> DeleteCommentCallback,
                                         Action<Exception> onError)
        {
            return;
        }
        #endregion

        #region Like operations
        public static async void SaveFavToAzure(AppContext context)
        {
            try
            {
                HttpResponseMessage msg;

                LikeData like = new LikeData();
                DateTime actionTime = DateTime.UtcNow;
                like.PartitionKey = actionTime.ToString("yyyy");
                like.RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - actionTime.Ticks, Guid.NewGuid());
                like.Timestamp = actionTime.ToString();
                like.BreadDate = Util.GetShortNavUrl(context.currentDisplayDate);

                string jsonLike = JsonConvert.SerializeObject(like);
                StringContent content = new StringContent(jsonLike, Encoding.UTF8, "application/json");

                using (var client = new HttpClient())
                {
                    msg = await client.PostAsync(new Uri(LikeAPIUri), content).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        public static void GetFavCountFromAzure(DateTime breadDate,
                                               Action<string> GetFavCallback,
                                               Action<Exception> onError)
        {
            try
            {
                string BreadDate = Util.GetShortNavUrl(breadDate);
                string url = LikeAPIUri + "?BreadDate=" + BreadDate;
                //string getResults = await HttpService.Get(new Uri(url));
                Uri uri = new Uri(url);
                HttpService.Get(uri,
                    delegate(string result)
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() => { GetFavCallback(result); });
                    },
                    delegate(string uriString, Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        Deployment.Current.Dispatcher.BeginInvoke(() => { onError(ex); });
                    });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                Deployment.Current.Dispatcher.BeginInvoke(() => { onError(ex); });
            }    
        }

        public static async void RemoveFavFromAzure(DateTime breadDate)
        {
            try
            {
                HttpResponseMessage msg;
                LikeData like = new LikeData();
                like.BreadDate = Util.GetShortNavUrl(breadDate);
                string jsonLike = JsonConvert.SerializeObject(like);
                StringContent content = new StringContent(jsonLike, Encoding.UTF8, "application/json");

                using (var client = new HttpClient())
                {
                    msg = await client.PostAsync(new Uri(UnLikeAPIUri), content).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        public static DailyVerse FindAmen(DateTime breadDate)
        {
            BreadCache<DateTime, DailyVerse> storedAmen = IsolatedStorageHelper.GetObject<BreadCache<DateTime, DailyVerse>>("CachedBread");
            if (storedAmen != null)
            {
                DailyVerse dv;
                if (storedAmen.TryGetValue(breadDate, out dv))
                {
                        return dv; 
                }
            }
            return null;
        }

        public static void RecordAmen(AppContext context, bool fav)
        {
            BreadCache<DateTime, DailyVerse> storedAmen = IsolatedStorageHelper.GetObject<BreadCache<DateTime, DailyVerse>>("CachedBread");
            if (storedAmen != null)
            {
                DailyVerse dv;
                if (storedAmen.TryGetValue(context.currentDisplayDate, out dv))
                {
                    // cached in the past, didn't cache some of the content, proceed to update or fill in the cache                        
                    dv.breadDate = context.currentDisplayDate;
                    dv.breadContent = context.BreadContent;
                    dv.verseContent = context.VerseContent;
                    dv.articleVerse = context.ArticleVerse;
                    dv.breadUri = context.BreadUri.ToString();                       

                    // mark as personal favorite if it's cached already
                    dv.personalFav = fav;
                    IsolatedStorageHelper.SaveObject("CachedBread", storedAmen);

                    // cached in the past, now needs to update the favorite count on server
                    if (fav)
                    {
                        SaveFavToAzure(context);
                    }
                    return;                    
                }
            }

            // it's not cached before.  If it's a personal fav or within last 3 days, save it
            if (fav || (System.DateTime.Today - context.currentDisplayDate).Days < 3)
            {
                if (storedAmen == null)
                {
                    storedAmen = new BreadCache<DateTime, DailyVerse>();
                }
                DailyVerse newVerse = new DailyVerse(context.VerseName,
                                                        context.BreadUri.ToString(),
                                                        context.BreadName,
                                                        context.currentDisplayDate,
                                                        context.BreadContent,
                                                        context.VerseContent,
                                                        context.ArticleVerse,
                                                        fav);
                storedAmen.Set(context.currentDisplayDate, newVerse);
                IsolatedStorageHelper.SaveObject("CachedBread", storedAmen);

                if (fav)
                    SaveFavToAzure(context);
            }
        }

        public static void RemoveAmen(DailyVerse dv)
        {
            BreadCache<DateTime, DailyVerse> savedAmen = IsolatedStorageHelper.GetObject<BreadCache<DateTime, DailyVerse>>("CachedBread");

            RemoveFavFromAzure(dv.breadDate);

            if (savedAmen != null)
            {
                DailyVerse savedDv;
                if (savedAmen.TryGetValue(dv.breadDate, out savedDv))
                {
                    // keep it in the cache, but remove the fav flag
                    savedDv.personalFav = false;
                    IsolatedStorageHelper.SaveObject("CachedBread", savedAmen);
                }
            }

        }
        #endregion

        #region html manipulation
        public static string ConvertExtendedASCII(string HTML)
        {
            string retVal = "";
            char[] s = HTML.ToCharArray();

            foreach (char c in s)
            {
                if (Convert.ToInt32(c) > 127)
                    retVal += "&#" + Convert.ToInt32(c) + ";";
                else
                    retVal += c;
            }

            return retVal;
        }

        public static string StripHTML(string source)
        {
            try
            {
                string result;

                // Remove HTML Development formatting
                // Replace line breaks with space
                // because browsers inserts space
                result = source.Replace("\r", " ");
                // Replace line breaks with space
                // because browsers inserts space
                result = result.Replace("\n", " ");
                // Remove step-formatting
                result = result.Replace("\t", string.Empty);
                // Remove repeating spaces because browsers ignore them
                result = System.Text.RegularExpressions.Regex.Replace(result,
                                                                      @"( )+", " ");

                // Remove the header (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*head([^>])*>", "<head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*head( )*>)", "</head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<head>).*(</head>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);


                // remove all scripts (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*script([^>])*>", "<script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*script( )*>)", "</script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"(<script>)([^(<script>\.</script>)])*(</script>)",
                //         string.Empty,
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<script>).*(</script>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // remove all styles (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*style([^>])*>", "<style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*style( )*>)", "</style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<style>).*(</style>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert tabs in spaces of <td> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*td([^>])*>", "\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line breaks in places of <BR> and <LI> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<br />", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*li( )*>", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line paragraphs (double line breaks) in place
                // if <P>, <DIV> and <TR> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*div([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*tr([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*p([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // Remove remaining tags like <a>, links, images,
                // comments etc - anything that's enclosed inside < >
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<[^>]*>", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // replace special characters:
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @" ", " ",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&bull;", " * ",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&lsaquo;", "<",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&rsaquo;", ">",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&trade;", "(tm)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&frasl;", "/",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&lt;", "<",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&gt;", ">",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&copy;", "(c)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&reg;", "(r)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove all others. More can be added, see
                // http://hotwired.lycos.com/webmonkey/reference/special_characters/
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&(.{2,6});", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // for testing
                //System.Text.RegularExpressions.Regex.Replace(result,
                //       this.txtRegex.Text,string.Empty,
                //       System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // make line breaking consistent
                result = result.Replace("\n", "\r");

                // Remove extra line breaks and tabs:
                // replace over 2 breaks with 2 and over 4 tabs with 4.
                // Prepare first to remove any whitespaces in between
                // the escaped characters and remove redundant tabs in between line breaks
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\t)", "\t\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\r)", "\t\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\t)", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove redundant tabs
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove multiple tabs following a line break with just one tab
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Initial replacement target string for line breaks
                //string breaks = "\r\r\r";
                //// Initial replacement target string for tabs
                //string tabs = "\t\t\t\t\t";
                //for (int index = 0; index < result.Length; index++)
                //{
                //    result = result.Replace(breaks, "\r\r");
                //    result = result.Replace(tabs, "\t\t\t\t");
                //    breaks = breaks + "\r";
                //    tabs = tabs + "\t";
                //}

                // strip leading spaces
                result = System.Text.RegularExpressions.Regex.Replace(result,
                            @"^\s+", String.Empty,
                            System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // That's it.
                return result;
            }
            catch
            {
                //MessageBox.Show("Error");
                return source;
            }
        }

        public static string ExtractContentUrl(DateTime date, string panelResults)
        {
            // get http://odb.org/ and then from that page get the real content page url
            string partialUrl = Util.GetNavUrl(date).ToString();
            int urlStartIndex = panelResults.IndexOf(partialUrl);
            int urlEndIndex = panelResults.IndexOf("\"", urlStartIndex);
            string contentUrl = panelResults.Substring(urlStartIndex, urlEndIndex - urlStartIndex);
            return contentUrl;
        }

        public static string ExtractVerseUrl(string getResults)
        {
            // retrieve the bible verse
            int startIndex = getResults.IndexOf("passage-box");
            int hrefStartIndex = getResults.IndexOf("href=", startIndex) + 6;
            int hrefEndIndex = getResults.IndexOf("\"", hrefStartIndex);
            string url = getResults.Substring(hrefStartIndex, hrefEndIndex - hrefStartIndex) + "&version=NKJV";
            return url;
        }

        public static void ExtractContent(ref AppContext context, string getResults)
        {
            // get the title of the daily bread
            int startIndex = getResults.IndexOf("entry-thumbnail");
            startIndex = getResults.IndexOf("title=", startIndex) + 7;
            int endIndex = getResults.IndexOf("\"", startIndex);
            context.BreadName = getResults.Substring(startIndex, endIndex - startIndex); // "You had to act"

            // get the ref bible text
            startIndex = getResults.IndexOf("passage-box");
            int refBibleStart = getResults.IndexOf("_blank", startIndex) + 8;
            int refBibleEnd = getResults.IndexOf("</a>", refBibleStart);
            context.VerseName = getResults.Substring(refBibleStart, refBibleEnd - refBibleStart);// "John 3:7-16"

            // get the bread main content
            startIndex = getResults.IndexOf("post-content") + 15;
            endIndex = getResults.IndexOf("<span class=\"universal-share\">");
            string content = getResults.Substring(startIndex, endIndex - startIndex);
            content = Util.StripHTML(content);

            // Get the short verse 
            int articleverseStartingPos = getResults.IndexOf("verse-box") + 11;
            int articleverseEndPos = getResults.IndexOf("</a>", articleverseStartingPos);
            string verse = getResults.Substring(articleverseStartingPos, articleverseEndPos - articleverseStartingPos);
            verse = Util.StripHTML(verse);
            context.ArticleVerse = verse;

            context.BreadContent = context.currentDisplayDate.ToLongDateString()
                                            + "\n\n"
                                            + context.ArticleVerse
                                            + "\n\n"
                                            + content;
            return;
        }

        public static string ExtractVerseContent(string refBibleResults)
        {
            StringBuilder refBibleVerse = new StringBuilder("<html><body>");
            int refStartIndex = refBibleResults.IndexOf("<span id=\"en-NKJV");
            int refEndIndex = refBibleResults.IndexOf("<div class=\"publisher-info-bottom", refStartIndex);
            refBibleVerse.Append(refBibleResults.Substring(refStartIndex, refEndIndex - refStartIndex));
            refBibleVerse.Append("</body></html>");
            refBibleResults = refBibleResults.Substring(refStartIndex, refEndIndex - refStartIndex);

            //strip the footnote reference
            refStartIndex = refBibleResults.IndexOf("<sup data-fn");
            while (refStartIndex != -1)
            {
                refEndIndex = refBibleResults.IndexOf("</sup>", refStartIndex);
                refBibleResults = refBibleResults.Remove(refStartIndex, refEndIndex - refStartIndex + 6);
                refStartIndex = refBibleResults.IndexOf("<sup data-fn");
            }

            //strip the cross reference
            refStartIndex = refBibleResults.IndexOf("<sup class='crossreference'");
            while (refStartIndex != -1)
            {
                refEndIndex = refBibleResults.IndexOf("</sup>", refStartIndex);
                refBibleResults = refBibleResults.Remove(refStartIndex, refEndIndex - refStartIndex + 6);
                refStartIndex = refBibleResults.IndexOf("<sup class='crossreference'");
            }

            return StripHTML(refBibleResults);
        }
        #endregion

    }
}
